home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / pcl4c35.zip / AMODEM.C next >
Text File  |  1993-04-25  |  10KB  |  287 lines

  1. /*
  2. **  ASCII text file transfer using XON / OFF flow control protocol.
  3. **  Transfer ASCII files only. Do not attempt to transfer binary files.
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <fcntl.h>
  8. #include <sys\types.h>
  9. #include <sys\stat.h>
  10.  
  11. #include "pcl4c.h"
  12. #include "ascii.h"
  13.  
  14. #define FALSE 0
  15. #define TRUE !FALSE
  16.  
  17. #define ONE_SECOND 18
  18.  
  19. extern int GetChar();
  20. extern int PutChar();
  21.  
  22. char lastXchar;     /* last XON or XOFF sent */
  23.  
  24. int TxAscii(Port,Filename,Buffer,Length,SyncFlag,CharPace,TermChar,EchoFlag)
  25. int Port;            /* COM port [0..3] */
  26. char Filename[];     /* filename buffer */
  27. char Buffer[];       /* data buffer */
  28. int Length;          /* size of Buffer */
  29. int SyncFlag;        /* synchronize with XON 1st */
  30. int CharPace;        /* millisecond delay after sending each character */
  31. int TermChar;        /* termination character (0x00 ==> none) */
  32. int EchoFlag;        /* do local echo if TRUE */
  33. {int i;
  34.  int Code;           /* return code */
  35.  int Handle;         /* file Handle */
  36.  char LastChar;      /* last character sent */
  37.  int TxChars = 0;    /* # characters transmitted */
  38.  int Count;          /* # bytes read from disk */
  39.  char Temp[81];      /* temporary buffer */
  40.  /* begin */
  41.  Handle = open(Filename,O_RDONLY|O_BINARY,S_IREAD);
  42.  if(Handle<0)
  43.      {strcpy(Temp,"Cannot open ");
  44.       strcat(Temp,Filename);
  45.       DisplayLine(Temp,NULL,0);
  46.       return(FALSE);
  47.      }
  48.  /* do we wait for XON before starting ? */
  49.  if(SyncFlag)
  50.    {/* wait for incoming XON */
  51.     DisplayLine("ASCII: Waiting for XON",NULL,0);
  52.     while(1)
  53.        {if(SioBrkKey())
  54.           {DisplayLine("Canceled by USER",NULL,0);
  55.            return(FALSE);
  56.           }
  57.         Code = SioGetc(Port,ONE_SECOND);
  58.         if(Code==-1) continue;
  59.         if(Code<0) return(FALSE);
  60.         if((char)Code==XON)
  61.            {DisplayLine("ASCII: initial XON received",NULL,0);
  62.             /* slight delay */
  63.             SioDelay(ONE_SECOND/2);
  64.             break;
  65.            }
  66.         /* received character not XON */
  67.         MyCrtWrite((char)Code);
  68.        }
  69.    }
  70.  /* begin transfer */
  71.  lastXchar =  XON;
  72.  DisplayLine("ASCII: Starting send",NULL,0);
  73.  while(SioKeyPress()) SioKeyRead();
  74.  /* clear comm port */
  75.  SioRxFlush(Port);
  76.  /* send ascii file ( stop at ^Z ) */
  77.  while(1)
  78.      {/* read next buffer from disk */
  79.       Count = read(Handle,Buffer,Length);
  80.       if(Count==0) break;
  81.       if(Count<0)
  82.           {SayError(Port,"Error on disk read");
  83.            return(FALSE);
  84.           }
  85.       /* send one byte at a time */
  86.       for(i=0;i<Count;i++)
  87.           {/* User ABORTS ? */
  88.            if(UserAborts(Port)) return(FALSE);
  89.            /* send byte */
  90.            LastChar = Buffer[i];
  91.            if(EchoFlag) MyCrtWrite(LastChar);
  92.            /* send the character */
  93.            PutChar(Port,LastChar);
  94.            if(CharPace>0) SioDelay(CharPace);
  95.            /* slight delay after each line */
  96.            if(LastChar==LF) SioDelay(4*(CharPace+1));
  97.            TxChars++;
  98.            /* ^Z marks the end of a text file */
  99.            if(LastChar==CTLZ) break;
  100.            /* check for incoming XON */
  101.            if(lastXchar==XON)
  102.                 {/* check for incoming XON / XOFF */
  103.                  Code = GetChar(Port,0);
  104.                  if(Code>0)
  105.                     {/* is byte a XOFF ? */
  106.                      if((char)Code==XOFF)
  107.                          {/* wait for XON */
  108.                           DisplayLine("XOFF received",NULL,0);
  109.                           lastXchar = XOFF;
  110.                           /* wait for XON */
  111.                           while(1)
  112.                               {/* user want to quit ? */
  113.                                if(SioBrkKey())
  114.                                    {DisplayLine("Canceled by USER",NULL,0);
  115.                                     return(FALSE);
  116.                                    }
  117.                                Code = GetChar(Port,ONE_SECOND);
  118.                                if((char)Code==XON)
  119.                                    {DisplayLine("XON  received",NULL,0);
  120.                                     lastXchar = XON;
  121.                                     break;
  122.                                    }
  123.                               } /* end -- while */
  124.                          } /* end -- if(XOFF) */
  125.                     } /* end -- if(Code) */
  126.                 } /* end -- if(XON) */
  127.  
  128.           } /* end -- for(i) */
  129.      } /* end -- while */
  130.  close(Handle);
  131.  /* send termination character */
  132.  if(TermChar) PutChar(Port,TermChar);
  133.  DisplayLine("ASCII: Transfer Complete",NULL,0);
  134.  return(TRUE);
  135. } /* end -- TxAcsii */
  136.  
  137. int RxAscii(Port,Filename,Buffer,Length,RxQueSize,SyncFlag,TermChar,TimeOut,EchoFlag)
  138. int Port;            /* COM port [0..3] */
  139. char Filename[];     /* filename buffer */
  140. char Buffer[];       /* data buffer */
  141. int Length;          /* length of data buffer */
  142. int RxQueSize;       /* size of PCL receive buffer */
  143. int SyncFlag;        /* synchronize with XON 1st */
  144. int TermChar;        /* termination character (0x00 ==> none) */
  145. int TimeOut;         /* delay (seconds) before assuming that sender is done */
  146. int EchoFlag;        /* do local echo if TRUE */
  147. {int i;
  148.  int Handle;         /* file Handle */
  149.  int Code;           /* return code */
  150.  int lo;             /* receive queue low water mark */
  151.  int hi;             /* receive queue high water mark */
  152.  int Index;          /* buffer index */
  153.  int QueSize;        /* current PCL receive queue size */
  154.  int RxChars = 0;    /* # received chars */
  155.  int Count;          /* # characters written to disk */
  156.  char Temp[81];      /* temporary buffer */
  157.  long LastTime;      /* time last character was received */
  158.  /* begin */
  159.  lastXchar = XON;
  160.  lo = RxQueSize / 8;
  161.  hi = 5 * lo;
  162.  DisplayLine("ASCII: Starting receive ",NULL,0);
  163.  while(SioKeyPress()) SioKeyRead();
  164.  /* clear comm port */
  165.  SioRxFlush(Port);
  166.  /* open file passed in Filename[] for write */
  167.  Handle = open(Filename,O_CREAT|O_TRUNC|O_WRONLY|O_BINARY,S_IWRITE);
  168.  if(Handle<0)
  169.      {strcpy(Temp,"Cannot open ");
  170.       strcat(Temp,Filename);
  171.       DisplayLine(Temp,NULL,0);
  172.       return(FALSE);
  173.      }
  174.  /* sync with XON 1st ? */
  175.  if(SyncFlag)
  176.     {DisplayLine("ASCII: Sending initial XON",NULL,0);
  177.      while(1)
  178.         {SioPutc(Port,XON);
  179.          Code = SioGetc(Port,ONE_SECOND);
  180.          if(Code==-1) continue;
  181.          /* transmitter is sending ! */
  182.          SioUnGetc(Port,Code);
  183.          break;
  184.         }
  185.     }
  186.  /* receive text */
  187.  LastTime = SioTimer();
  188.  Index = 0;
  189.  while(1)
  190.      {/* user want to quit ? */
  191.       if(SioBrkKey())
  192.           {DisplayLine("Canceled by USER",NULL,0);
  193.            return(FALSE);
  194.           }
  195.       /* check on PCL receive queue size */
  196.       QueSize = SioRxQue(Port);
  197.       if((QueSize>hi)&&(lastXchar==XON))
  198.           {PutChar(Port,XOFF);
  199.            lastXchar = XOFF;
  200.            DisplayLine("sending XOFF(1)",NULL,0);
  201.            /*printf("\nQueSize=%d lo=%d hi=%d\n",QueSize,lo,hi);*/
  202.           }
  203.       if((QueSize<lo)&&(lastXchar==XOFF))
  204.           {PutChar(Port,XON);
  205.            lastXchar = XON;
  206.            DisplayLine("sending XON ",NULL,0);
  207.           }
  208.       /* User ABORTS ? */
  209.       if(UserAborts(Port)) return(FALSE);
  210.       /* get next byte */
  211.       Code = GetChar(Port,ONE_SECOND);
  212.       if(Code==-1)
  213.          {/* done if having exceeded timeout */
  214.           if(SioTimer()-LastTime>ONE_SECOND*TimeOut)
  215.             {/* sender must be done */
  216.              Buffer[Index] = CTLZ;
  217.              break;
  218.             }
  219.           continue;
  220.          }
  221.       /* ignore 1st character if it is a 0 */
  222.       if((RxChars==0)&&((char)Code=='\0')) continue;
  223.       LastTime = SioTimer();
  224.       /* ignore XON & XOFF ( since we are the receiver ) */
  225.       if((char)Code==XON) continue;
  226.       if((char)Code==XOFF) continue;
  227.       /* received a character */
  228.       Buffer[Index++] = (char)Code;
  229.       RxChars++;
  230.       /* TermChar marks the end of a text file */
  231.       if((char)Code==TermChar)
  232.           {/* replace TermChar with ^Z */
  233.            Buffer[Index-1] = CTLZ;
  234.            RxChars++;
  235.            break;
  236.           }
  237.       if(EchoFlag) MyCrtWrite((char)Code);
  238.       if(Index==Length)
  239.           {/* send XOFF to transmitter */
  240.            PutChar(Port,XOFF);
  241.            lastXchar = XOFF;
  242.            DisplayLine("sending XOFF(2)",NULL,0);
  243.            /* write disk file */
  244.            Count = write(Handle,Buffer,Index);
  245.            if(Count<0)
  246.                {SayError("Disk read error",NULL);
  247.                 SioDelay(ONE_SECOND);
  248.                 return(FALSE);
  249.                }
  250.            /* send XON to sender */
  251.            PutChar(Port,XON);
  252.            lastXchar = XON;
  253.            DisplayLine("sending XON ",NULL,0);
  254.            Index = 0;
  255.           } /* end -- if */
  256.      } /* end -- while */
  257.  /* write any remaining data in buffer */
  258.  if(Index>0)
  259.      {Count = write(Handle,Buffer,Index);
  260.       if(Count<0)
  261.           {SayError("Disk read error",NULL);
  262.            SioDelay(ONE_SECOND);
  263.            return(FALSE);
  264.           }
  265.      } /* end -- if */
  266.  close(Handle);
  267.  DisplayLine("ASCII: Transfer Complete",NULL,0);
  268.  return(TRUE);
  269. } /* RxAscii */
  270.  
  271. int UserAborts(Port)
  272. int Port;
  273. {char UserChar;
  274.  /* user aborts ? */
  275.  if(SioKeyPress())
  276.     {UserChar = (char)SioKeyRead();
  277.      if(UserChar==CAN)
  278.        {TxCAN(Port);
  279.         SioPutc(Port,ETX);
  280.         DisplayLine("*** Canceled by USER ***",NULL,0);
  281.         return(TRUE);
  282.        }
  283.      /* send user char */
  284.      SioPutc(Port,UserChar);
  285.     }
  286.  return(FALSE);
  287. } /* UserAborts */